package com.javabasic.algorithm.lru;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author xiongmin
 * @Description //TODO
 * @Date 2020/4/23 11:45
 * @Version 1.0
 **/
public class MyLruCacheTest {


    public static void main(String[] args) {
        CorrentTest();

        try {
            AsyncTest();

//            CorrentWithExpireTest();
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }

    public static void CorrentTest() {
        MyLruCacheWithExpireTime<Integer, String> myLruCache = new MyLruCacheWithExpireTime<>(3);
        myLruCache.put(1, "Java");
        System.out.println(myLruCache.get(1));// Java
        myLruCache.remove(1);
        System.out.println(myLruCache.get(1));// null
        myLruCache.put(2, "C++");
        myLruCache.put(3, "Python");
        System.out.println(myLruCache.get(2));//C++
        myLruCache.put(4, "C");
        myLruCache.put(5, "PHP"); // maxCapacity of cache reached
        System.out.println(myLruCache.get(2));// C++
    }

    public static void CorrentWithExpireTest() throws InterruptedException {
        MyLruCacheWithExpireTime<Integer,String> myLruCache = new MyLruCacheWithExpireTime<>(3);
        myLruCache.put(1,"Java",3000);
        myLruCache.put(2,"C++",3000);
        myLruCache.put(3,"Python",1500);
        System.out.println(myLruCache.size());//3
        Thread.sleep(2000);
        System.out.println(myLruCache.size());//2
        myLruCache.close();
        System.out.println(myLruCache.size());//2
    }

    public static void AsyncTest() throws InterruptedException {
        int threadNum = 10;
        int batchSize = 10;
        //init cache
        MyLruCacheWithExpireTime<String, Integer> myLruCache = new MyLruCacheWithExpireTime<>(batchSize * 10);
        //init thread pool with 10 threads
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(threadNum);
        //init CountDownLatch with 10 count
        CountDownLatch latch = new CountDownLatch(threadNum);
        AtomicInteger atomicInteger = new AtomicInteger(0);
        long startTime = System.currentTimeMillis();
        for (int t = 0; t < threadNum; t++) {
            fixedThreadPool.submit(() -> {
                for (int i = 0; i < batchSize; i++) {
                    int value = atomicInteger.incrementAndGet();
                    myLruCache.put("id" + value, value);
                }
                latch.countDown();
            });
        }
        //wait for 10 threads to complete the task
        latch.await();
        fixedThreadPool.shutdown();
        System.out.println("Cache size:" + myLruCache.size());//Cache size:100
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        System.out.println(String.format("Time cost：%dms", duration));//Time cost：511ms
    }
}
